package org.springblade.modules.analyse.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springblade.common.echarts.*;
import org.springblade.modules.analyse.service.AnalyseService;
import org.springblade.modules.classes.entity.*;
import org.springblade.modules.classes.service.*;
import org.springblade.modules.course.entity.CourseEntity;
import org.springblade.modules.course.service.ICourseService;
import org.springblade.modules.item.service.IStockLogService;
import org.springblade.modules.library.service.IQuestionBankService;
import org.springblade.modules.log.entity.IntegralLogEntity;
import org.springblade.modules.log.service.IIntegralLogService;
import org.springblade.modules.resource.enums.AttachType;
import org.springblade.modules.system.entity.Role;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IRoleService;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.teaching.entity.CourseChapterSubFileEntity;
import org.springblade.modules.teaching.service.ICourseChapterSubFileService;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author junxin
 */
@Service
@AllArgsConstructor
public class AnalyseServiceImpl implements AnalyseService {

	private final IStockLogService stockLogService;
	private final ITrainingPlanService trainingPlanService;
	private final IClassesService classesService;
	private final IRoleService roleService;
	private final IUserService userService;
	private final ICourseService courseService;
	private final ICourseChapterSubFileService courseChapterSubFileService;
	private final IQuestionBankService questionBankService;
	private final IClassesUserService classesUserService;
	private final IClassesPlanService classesPlanService;
	private final ITrainingPlanCourseService trainingPlanCourseService;
	private final IIntegralLogService integralLogService;
	@Override
	public EchartsModel itemStockLogAnalyse() {
		List<EchartsQueryModel> list=stockLogService.itemStockLogAnalyseByBorrow();
		EchartsModel echartsModel=new EchartsModel();
		Title title=new Title();
		title.setText("教具借出频次");

		//设置legend
		Legend legend=new Legend();
		List<Object> legendDataList=new ArrayList<>();
		legendDataList.add("数量");


		//x轴设置
		XAxis xAxis=new XAxis();
		List<Object> xAxisDataList=new ArrayList<>();
		List<Series> series=new ArrayList<>();
		List<Object> seriesVoDataList=new ArrayList<>();
		for (EchartsQueryModel model:list){
			xAxisDataList.add(model.getAttributeName());
			seriesVoDataList.add(model.getNum());
		}
		Series seriesVo=new Series();
		seriesVo.setName("数量");
		seriesVo.setData(seriesVoDataList);
		seriesVo.setType("bar");

		//把值放入echartsModel
		legend.setData(legendDataList);
		xAxis.setData(xAxisDataList);
		series.add(seriesVo);
		echartsModel.setTitle(title);
		echartsModel.setLegend(legend);
		echartsModel.setxAxis(xAxis);
		echartsModel.setSeries(series);

		return echartsModel;
	}

	@Override
	public Map<String, String> bigdataBaseData(Integer type) {
		Map<String, String> resultMap=new HashMap<>();
		DecimalFormat df=new DecimalFormat("0.##");//保留有意义的小数点后两位 例如0.1
		long num=0;
		switch (type){
			case 1://年度培训计划数
				num = trainingPlanService.count();
				break;
			case 2://内部培训
				num= trainingPlanService.count(Wrappers.<TrainingPlanEntity>query().lambda().in(TrainingPlanEntity::getTrainingType,1,2));
				break;
			case 3: //相关方培训
				num= trainingPlanService.count(Wrappers.<TrainingPlanEntity>query().lambda().eq(TrainingPlanEntity::getTrainingType,3));
				break;
			case 4: //技能鉴定培训
				num = trainingPlanService.count(Wrappers.<TrainingPlanEntity>query().lambda().eq(TrainingPlanEntity::getTrainingType,4));
				break;
			case 5: //开展培训次数  统计开了几个班
				num= classesService.count();
				break;
			case 6://培训合格率  每个班级合格的人数超过6成就算合格
				List<ClassesEntity> classesEntityList = classesService.list();
				if (CollectionUtils.isEmpty(classesEntityList)) break;
				int classesNum=classesEntityList.size();//班级数量
				int passClassesNum=0;//合格的班级数
				for (ClassesEntity classes:classesEntityList){
					//1.获得该班级的学生
					List<ClassesUserEntity> classesUserEntityList = classesUserService.list(Wrappers.<ClassesUserEntity>query()
						.lambda().eq(ClassesUserEntity::getClassesId, classes.getId()));
					//班级人数 如果班级人数为0 也算合格
					if (CollectionUtils.isEmpty(classesUserEntityList)){
						passClassesNum++;
						continue;
					}
					//2.获得该班级的培训计划课程
					//2.1 获得培训计划id
					ClassesPlanEntity classesPlanEntity = classesPlanService.getOne(Wrappers.<ClassesPlanEntity>query()
						.lambda().eq(ClassesPlanEntity::getClassesId, classes.getId()));
					if (null==classesPlanEntity) continue;
					//2.2获取培训计划课程的ids
					List<TrainingPlanCourseEntity> trainingPlanCourseList = trainingPlanCourseService.list(Wrappers.<TrainingPlanCourseEntity>query()
						.lambda().eq(TrainingPlanCourseEntity::getTrainingPlanId, classesPlanEntity.getPlanId()));
					if (CollectionUtils.isEmpty(trainingPlanCourseList)) continue;
					List<Long> courseIds = trainingPlanCourseList.stream()
						.map(TrainingPlanCourseEntity::getCourseId).collect(Collectors.toList());

					int classesUserPassNum=0;//当前班级的合格人数
					for (ClassesUserEntity classesUser :classesUserEntityList){
						boolean flag=false;
						for (Long courseId:courseIds){//遍历该学生的所有课程,如果都通过，表示该学生此培训通过
							flag = courseService.checkCourseComplete(courseId, classesUser.getUserId());
						}
						if (flag)classesUserPassNum++;
					}
					int size = classesUserEntityList.size();

					if (classesUserPassNum>=(size*0.6))passClassesNum++;
				}
				double result = passClassesNum * 1.0 / classesNum*100;
				if (0!=result){
					resultMap.put("value",df.format(result)+"%");
					return resultMap;
				}
				break;
			case 7://培训人次  所有班级人数之和
				num = classesUserService.count();
				break;
			case 8://积分达标率  只统计有积分的培训，计算达标的人数 除以 培训人次
				//1.首先获得有积分的培训计划
				//1.1查询有积分的课程 积分>0
				List<CourseEntity> courseList = courseService.list(Wrappers.<CourseEntity>query().lambda().gt(CourseEntity::getIntegral, 0));
				if (CollectionUtils.isEmpty(courseList))break;
				//课程ids
				List<Long> courseIds = courseList.stream().map(CourseEntity::getId).collect(Collectors.toList());

				//1.2 获得对应的培训计划
				List<TrainingPlanCourseEntity> planList = trainingPlanCourseService.list(Wrappers.<TrainingPlanCourseEntity>query().lambda()
					.in(TrainingPlanCourseEntity::getCourseId, courseIds));
				if (CollectionUtils.isEmpty(planList))break;

				//1.3 获得培训计划就对应的班级
				List<ClassesPlanEntity> classesPlanList = classesPlanService.list(Wrappers.<ClassesPlanEntity>query().lambda().
					in(ClassesPlanEntity::getPlanId, planList.stream().map(TrainingPlanCourseEntity::getTrainingPlanId).collect(Collectors.toList())));
				if (CollectionUtils.isEmpty(classesPlanList))break;

				//1.4 计算培训总人次
				long trainers = classesUserService.count(Wrappers.<ClassesUserEntity>query().lambda()
					.in(ClassesUserEntity::getClassesId, classesPlanList.stream().map(ClassesPlanEntity::getClassesId).collect(Collectors.toList())));
				//1.5 计算获得课程积分的人数
				long passNums = integralLogService.count(Wrappers.<IntegralLogEntity>query().lambda()
					.in(IntegralLogEntity::getIntegralResourcesId, courseIds));
				double result8 = passNums * 1.0 / trainers*100;
				resultMap.put("value",df.format(result8)+"%");
				return resultMap;
			case 9://内训师
				List<Role> teacherRolds = roleService.list(Wrappers.<Role>query().lambda().eq(Role::getRoleAlias, "teacher"));
				if (CollectionUtils.isNotEmpty(teacherRolds)){
					List<Long> ids=teacherRolds.stream().map( Role::getId).collect(Collectors.toList());
					num = userService.count(Wrappers.<User>query().lambda().in(User::getRoleId, ids));
				}
				break;
			case 10://课程数
				num= courseService.count();
				break;
			case 11://教材数  学习课件数量
				num = courseChapterSubFileService.count(Wrappers.<CourseChapterSubFileEntity>query().lambda()
					.eq(CourseChapterSubFileEntity::getAttachType, AttachType.COURSE_COURSEWARE.getCategory()));
				break;
			case 12://题库数
				num = questionBankService.count();
				break;
		}

		resultMap.put("value",String.valueOf(num));
		return resultMap;
	}


}
